package com.linxi.wordslog.wordslog

import android.app.AlertDialog
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.util.Log
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.core.content.edit
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.navigation.Navigation
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import com.linxi.wordslog.Injection
import com.linxi.wordslog.R
import com.linxi.wordslog.adapter.WordAdapter
import com.linxi.wordslog.data.room.Word
import com.linxi.wordslog.wordslogviewmodel.IS_USING_CARD_VIEW
import com.linxi.wordslog.wordslogviewmodel.VIEW_TYPE
import com.linxi.wordslog.wordslogviewmodel.WordViewModel
import kotlinx.android.synthetic.main.activity_words.*
import kotlinx.android.synthetic.main.fragment_word_log.*

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [WordLogFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class WordLogFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    private val wordViewModel by viewModels<WordViewModel> {
        Injection.provideWordViewModelFactory(
            requireActivity()
        )
    }

    private lateinit var wordAdapter1: WordAdapter
    private lateinit var wordAdapter2: WordAdapter
    private var filterWords: LiveData<List<Word>> = MutableLiveData()
    private lateinit var allWords: List<Word>
    private var undoAction = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
        wordAdapter1 = WordAdapter(false, wordViewModel)
        wordAdapter2 = WordAdapter(true, wordViewModel)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        requireActivity().toolbar.visibility = View.VISIBLE
        val toolbar = requireActivity().toolbar
        toolbar.setNavigationIcon(R.drawable.ic_user_logo)
        return inflater.inflate(R.layout.fragment_word_log, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        val imm =
            requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(requireActivity().currentFocus?.windowToken, 0)

        val shp = requireActivity().getSharedPreferences(VIEW_TYPE, Context.MODE_PRIVATE)
        val isUsing = shp.getBoolean(IS_USING_CARD_VIEW, false)
        filterWords = wordViewModel.getAllWords()
        filterWords.observe(viewLifecycleOwner, Observer<List<Word>> { words ->
            val size = wordAdapter1.itemCount
            allWords = words
            if (size != words.size) {
                if (size < words.size && !undoAction) {
                    recyclerView.smoothScrollBy(0, -200)
                }
                undoAction = false
                wordAdapter1.submitList(words)
                wordAdapter2.submitList(words)
            }
        })
        ItemTouchHelper(object: ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.START or ItemTouchHelper.END) {
            private val wasteIcon: Drawable? = ContextCompat.getDrawable(requireActivity(), R.drawable.ic_baseline_delete_forever_24)
            private val background: Drawable = ColorDrawable(Color.LTGRAY)

            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                target: RecyclerView.ViewHolder
            ): Boolean = false

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                val wordToDelete = allWords[viewHolder.adapterPosition]
                wordViewModel.deleteWords(wordToDelete)
                Log.d("TAG", "onSwiped: $direction")
                Snackbar.make(requireView().findViewById(R.id.wordFragmentView), "删除了一个词汇", Snackbar.LENGTH_LONG)
                    .setAction("撤销") {
                        wordViewModel.insertWords(wordToDelete)
                        undoAction = true
                    }
                    .show()
            }
            // 在滑动的时候，画出浅灰色背景和垃圾桶图标
            override fun onChildDraw(
                c: Canvas,
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                dX: Float,
                dY: Float,
                actionState: Int,
                isCurrentlyActive: Boolean
            ) {
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
                if (wasteIcon == null) return

                val itemView = viewHolder.itemView
                val iconMargin = (itemView.height - wasteIcon.intrinsicHeight) / 2

                val iconLeft: Int
                val iconRight: Int
                val iconTop: Int = itemView.top + iconMargin
                val iconBottom: Int = iconTop + wasteIcon.intrinsicHeight

                val backTop: Int = itemView.top
                val backBottom: Int = itemView.bottom
                val backLeft: Int
                val backRight: Int

                when {
                    dX > 0 -> {
                        backLeft = itemView.left
                        backRight = itemView.left + dX.toInt()
                        iconLeft = itemView.left + iconMargin
                        iconRight = iconLeft + wasteIcon.intrinsicWidth

                        background.setBounds(backLeft, backTop, backRight, backBottom)
                        wasteIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom)
                    }
                    dX < 0 -> {
                        backRight = itemView.right
                        backLeft = itemView.right + dX.toInt()
                        iconRight = itemView.right - iconMargin
                        iconLeft = iconRight - wasteIcon.intrinsicWidth

                        background.setBounds(backLeft, backTop, backRight, backBottom)
                        wasteIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom)
                    }
                    else -> {
                        background.setBounds(0, 0, 0, 0)
                        wasteIcon.setBounds(0, 0, 0, 0)
                    }
                }

                background.draw(c)
                wasteIcon.draw(c)
            }

        }).attachToRecyclerView(recyclerView)



        recyclerView.apply {
            layoutManager = LinearLayoutManager(requireActivity())
            itemAnimator = object : DefaultItemAnimator() {
                override fun onAnimationFinished(viewHolder: RecyclerView.ViewHolder) {
                    super.onAnimationFinished(viewHolder)
                    val linearLayoutManager = layoutManager as LinearLayoutManager?
                    if (linearLayoutManager != null) {
                        val firstPosition = linearLayoutManager.findFirstVisibleItemPosition()
                        val lastPosition = linearLayoutManager.findLastVisibleItemPosition()
                        for (i in firstPosition..lastPosition) {
                            val holder =
                                findViewHolderForAdapterPosition(i) as WordAdapter.WordViewHolder?
                            holder?.textViewId?.text = (i + 1).toString()
                        }
                    }
                }
            }
            adapter = if (isUsing) wordAdapter2 else wordAdapter1
        }
        floatingActionButtonAdd.setOnClickListener {
            Navigation.findNavController(it).navigate(R.id.action_wordLogFragment_to_addFragment)
        }



    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        menu.clear()
        inflater.inflate(R.menu.menu, menu)
        initMenu(menu)
        super.onCreateOptionsMenu(menu, inflater)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.CleanAll -> {
                AlertDialog.Builder(requireActivity()).apply {
                    setMessage("是否清空数据")
                    setPositiveButton("是") {_, _ ->
                        wordViewModel.deleteAllWords()
                    }
                    setNegativeButton("否", null)
                    create()
                    show()
                }
            }
            R.id.switchView -> {
                val shp = requireActivity().getSharedPreferences(VIEW_TYPE, Context.MODE_PRIVATE)
                val isUsing = shp.getBoolean(IS_USING_CARD_VIEW, false)
                if (isUsing) {
                    recyclerView.adapter = wordAdapter1
                    shp.edit {
                        putBoolean(IS_USING_CARD_VIEW, false)
                        apply()
                    }
                } else {
                    recyclerView.adapter = wordAdapter2
                    shp.edit {
                        putBoolean(IS_USING_CARD_VIEW, true)
                        apply()
                    }
                }
            }
        }
        return super.onOptionsItemSelected(item)
    }


    private fun initMenu(menu: Menu) {
        val searchView = menu.findItem(R.id.app_bar_search).actionView as SearchView
//        searchView.maxWidth = 680
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(p0: String?): Boolean = false

            override fun onQueryTextChange(query: String?): Boolean {
                if (query == null) return false
                val pattern = query.trim()
                filterWords.removeObservers(viewLifecycleOwner)
                filterWords = wordViewModel.findWordsWithPattern(pattern)
                filterWords.observe(viewLifecycleOwner, Observer<List<Word>> {
                    val size = wordAdapter1.itemCount
                    allWords = it
                    if (size != it.size) {
                        wordAdapter1.submitList(it)
                        wordAdapter2.submitList(it)
                    }
                })
                return true
            }

        })
    }

    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment WordLogFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            WordLogFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}